package com.jml.单例模式.枚举.枚举单例原理;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;


//反射不能破解去创建枚举
public class EnumSingletonTest {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        EnumSingleton instance1 = EnumSingleton.INSTANCE;
        EnumSingleton instance2 = EnumSingleton.INSTANCE;
        System.out.println(instance1 == instance2);

        // 单例七种的，为什么枚举是最好的呢？防止java的反射和序列化破解
        Class<EnumSingleton> enumSingletonClass = EnumSingleton.class;
        // 没有无参构造函数...
        Constructor<EnumSingleton> declaredConstructor = enumSingletonClass.getDeclaredConstructor();
        EnumSingleton enumSingleton = declaredConstructor.newInstance();
        enumSingleton.add();
//       枚举底层是如何实现的
        //因为可以调用add方法，所以EnumSingleton.INSTANCE是一个对象，所以枚举本身就会一个人类.
        EnumSingleton instance = EnumSingleton.INSTANCE;
        EnumSingleton.INSTANCE.add();


        // 即使知道枚举的构造内容也无法通过反射进行实例化
        EnumSingleton[] values = EnumSingleton.values();
         //1.使用java的反射技术执行 枚举的有参构造函数..
        Class<EnumSingleton> enumSingletonClass1 = EnumSingleton.class;
        // 2.查找当前类是否有该构造函数..
        Constructor<EnumSingleton> declaredConstructor1 = enumSingletonClass1.getDeclaredConstructor(String.class, int.class);
        declaredConstructor1.setAccessible(true);
        // 3.调用反射方法初始化对象
        EnumSingleton enumSingleton1 = declaredConstructor1.newInstance("zhangsan", 20);
        enumSingleton1.add();

    }
    /**
     *  EnumSingleton.INSTANCE 是一个对象...  类  如何初始化呢？ 定义的枚举最终底层肯定是一个类  枚举在底层肯定转换为类
     *
     *  编译器会实现优化 底层会转换类
     */
}
